#ifndef CUSTYPEDEFH
#define CUSTYPEDEFH

#ifndef __HOST__
#include "ap_axi_sdata.h"
#include "hls_stream.h"
#include "ap_int.h"
#endif

// problem size
#define DATA_SIZE_W     64
#define DATA_SIZE_H     64
#define DATA_SIZE_N     64
#define DATA_SIZE       DATA_SIZE_W * DATA_SIZE_H * DATA_SIZE_N
#define DATA_SIZE_K     3
#define DATA_SIZE_M     64
#define KERNEL_SIZE     DATA_SIZE_K * DATA_SIZE_K * DATA_SIZE_N * DATA_SIZE_M
#define DMA_ALIGNMENT   64
#define VEC_SIZE        DATA_SIZE_K
#define OUTPUT_SIZE     (DATA_SIZE_W - DATA_SIZE_K + 1) * (DATA_SIZE_H - DATA_SIZE_K + 1) * DATA_SIZE_M

#define BUFFER_DEPTH    DATA_SIZE_W * DATA_SIZE_N

#define DATA_TYPE     float



#ifndef __HOST__
template<class T>
using k2k = ap_axiu<sizeof(T)*8,0,0,0>;

#define REFERENCE_STREAM(type, depth, name)\
hls::stream<type>& name
#include <stdio.h> 
#define k2kdef(t) k2k<decltype(t)>

#define GET_BIT(type) sizeof(type)*8
#endif

typedef unsigned int  uint;



#define DATA_TYPE   float


#define FADD_LAT 13
// coding style 1
//typedef ap_uint<VEC_SIZE*32> float_vec;
//typedef  hls::vector<float, VEC_SIZE> float_vec;
 // coding style 2
typedef struct {
   float data[VEC_SIZE];
} float_vec;

typedef struct {
   DATA_TYPE data[VEC_SIZE];
} vec_type;

typedef struct {
   DATA_TYPE data[DATA_SIZE_K];
} KNL_VEC;

typedef struct {
   vec_type data[FADD_LAT];
} vec_typer;

template<typename T>
T reg(T d){
    #pragma HLS PIPELINE II=1
    #pragma HLS LATENCY max=1 min=1
    #pragma HLS INLINE off
    return d;
}

#endif
